﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.WebPages;
using System.Web.WebPages.Html;

namespace System.Web.Mvc
{
    public static class MvcPager
    {
        public static int CurrentPageIndex
        {
            get;
            set;
        }

        public static int PageSize
        {
            get;
            set;
        }

        public static int RecordCount
        {
            get;
            set;
        }

        public static FormCollection Fcollection
        {
            get;
            set;
        }

        public static MethodType mtype
        {
            get;
            set;
        }

        public static string Pager(this HtmlHelper helper,string Id,string className,object htmlAttributes)
        {
            TagBuilder tb = new TagBuilder("table");
            tb.IdAttributeDotReplacement = "_";
            tb.GenerateId(Id);
            tb.AddCssClass(className);
            tb.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            tb.InnerHtml = GetNormalPage();
            return tb.ToString();
        }

        public static string GetNormalPage()
        {
            StringBuilder strUrl = new StringBuilder();
            strUrl.Append(HttpContext.Current.Request.Url.AbsolutePath + "?page={0}");

            if (Fcollection != null && mtype == MethodType.Post)
            {
                string[] FcKeys = Fcollection.AllKeys;
                for (int i = 0; i < FcKeys.Length; i++)
                {
                    if (FcKeys[i].ToLower() != "page")
                    {
                        strUrl.AppendFormat("&{0}={1}", FcKeys[i], Fcollection[i]);
                    }
                }
            }

            //获取get参数
            NameValueCollection nv = HttpContext.Current.Request.QueryString;
            string[] keys = nv.AllKeys;
            for (int i = 0; i < keys.Length; i++)
            {
                if(keys[i].ToLower()!="page")
                {
                    strUrl.AppendFormat("&{0}={1}",keys[i],nv[i]);                    
                }
            }


            int TotalPageNum=RecordCount/PageSize;
            int PageCount =RecordCount%PageSize>0?(TotalPageNum+1):TotalPageNum;//末页的Index
            StringBuilder sbPageNumStr = new StringBuilder();
            sbPageNumStr.Append("<tr><td>");
            string strTabA = "<span><a href='{0}'>{1}</a></span>";
            string strEnd = string.Format(strTabA, string.Format(strUrl.ToString(), PageCount), "末页");
            string strStart = string.Format(strTabA, string.Format(strUrl.ToString(), 1), "首页");
            string strPrevious = string.Format(strTabA, string.Format(strUrl.ToString(), CurrentPageIndex - 1), "上一页");
            string strNext = string.Format(strTabA, string.Format(strUrl.ToString(), CurrentPageIndex + 1), "下一页");
            #region 首页
            if (CurrentPageIndex == 1)
            {
                sbPageNumStr.Append("<span>首页</span>&nbsp;&nbsp");
            }
            else
            {
                sbPageNumStr.AppendFormat("<span>{0}</span>&nbsp;&nbsp",strStart);
            }
            #endregion

            #region 上一页
            if (CurrentPageIndex > 1)
            {
                sbPageNumStr.AppendFormat("<span>{0}</span>&nbsp;&nbsp", strPrevious);
            }
            else
            {
                sbPageNumStr.Append("<span>上一页</span>&nbsp;&nbsp");
            }
            #endregion

            sbPageNumStr.Append(GetNumericPage2(CurrentPageIndex,PageSize,RecordCount,PageCount,strUrl.ToString()));
            #region 下一页
            if (CurrentPageIndex <RecordCount)
            {
                sbPageNumStr.AppendFormat("<span>{0}</span>&nbsp;&nbsp", strNext); 
            }
            else
            {
                sbPageNumStr.Append("<span>下一页</span>&nbsp;&nbsp");
            }
            #endregion

            #region 末页
            if (CurrentPageIndex == RecordCount)
            {
                sbPageNumStr.Append("<span>末页</span>&nbsp;&nbsp");

            }
            else 
            {
                sbPageNumStr.AppendFormat("<span>{0}</span>&nbsp;&nbsp", strEnd);
            }
            #endregion   
            sbPageNumStr.Append("</td></tr>");
            return sbPageNumStr.ToString();
        }

        /// <summary>
        /// 假设有750条数据，每页10条，每组页码显示10个数字，页码显示形式如下：
        /// 1----10,10---20,20---30,....,70-----75
        /// </summary>
        /// <param name="CurrentPageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="RecordCount"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string GetNumericPage(int CurrentPageIndex, int PageSize, int RecordCount,int PageCount, string url)
        {
            int ShowNumCount = 10;//显示页码数
            int k = CurrentPageIndex / ShowNumCount;//k的值为：0,1,2,3...7,用来计算显示的一组页码的开始值，例如1,11,21，...71.
            int mod = CurrentPageIndex % ShowNumCount;//mod的值为 0<= mod <=ShowNumCount
            int LastPageCount = PageCount % ShowNumCount;//最后一页显示条数

            StringBuilder sb = new StringBuilder();

            ////控制点击数字整体向前显示
            //if (mod == 1 && k>0) { k--; }

            if (PageCount/ShowNumCount == k)
            {//最后一组页码
                mod = LastPageCount;
            }
            else
            {
                mod = ShowNumCount;
            }

            int StartNum = k * 10 + 1;
            int EndNum = k * 10 + mod;
            for (int i = StartNum; i <= EndNum; i++)
            {
                if (i == CurrentPageIndex)
                {
                    sb.AppendFormat("<span><font color=red><b>{0}</b></font></span>&nbsp;&nbsp;", i);
                }
                else
                {
                    sb.AppendFormat("<span><a href='{0}'>{1}</a></span>&nbsp;&nbsp;", string.Format(url, i), i);
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// 当前页码与当前显示的起始页码数差值相等
        /// </summary>
        /// <param name="CurrentPageIndex"></param>
        /// <param name="PageSize"></param>
        /// <param name="RecordCount"></param>
        /// <param name="PageCount"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string GetNumericPage2(int CurrentPageIndex, int PageSize, int RecordCount, int PageCount, string url)
        {
            int ShowNumCount = 10;//显示页码数
            int LastPageCount = PageCount % ShowNumCount;//最后一页显示条数
            int AddNum = 5;//当前页与起始页码，结束页码的差值
            int StartNum;
            int EndNum;
            if (CurrentPageIndex - AddNum <= 0)
            {//第一组页码数
                StartNum = 1;
                if (PageCount >= ShowNumCount)
                { EndNum = ShowNumCount; }
                else
                { EndNum = LastPageCount;}
            }
            else
            {
                StartNum = CurrentPageIndex - AddNum;
                if (PageCount < ShowNumCount)
                {
                    EndNum = PageCount;
                }
                else
                {
                    EndNum = CurrentPageIndex + AddNum;
                    if (EndNum > PageCount)
                    { EndNum = PageCount; }
                }
            }

            StringBuilder sb = new StringBuilder();
            for (int i = StartNum; i <= EndNum; i++)
            {
                if (i == CurrentPageIndex)
                {
                    sb.AppendFormat("<span><font color=red><b>{0}</b></font></span>&nbsp;&nbsp;", i);
                }
                else
                {
                    sb.AppendFormat("<span><a href='{0}'>{1}</a></span>&nbsp;&nbsp;", string.Format(url, i), i);
                }
            }
            return sb.ToString();
        }
    }

    public enum MethodType
    {
        Post,
        Get
    }
}
